<Link>

该组件页面上渲染的就是一个<a>标签超链接,但行为却和传统的<a>不一样。

<Link to="/">home</Link>
//等价于
<Link to="/" children={"home"} />

//渲染在页面上
<a href="/">home</a>

正常情况下,点击a标签,页面发生跳转,这个时候浏览器是有刷新过程的。而<Link>渲染的a标签,会阻止这一默认行为,通过类似于this.props.history.push({})的方式添加历史栈,并指向目标路由。


to:string|object

当属性to的值为字符串时,就如上例那样,代表目标路由。

当值为一个对象时,通常包含如下属性:

<Link to={{
    pathname:"/",
    search:"?name=geralt",
    hash:"#the-hash",
    state:{loading:true}
}} >home</Link>

pathname就是路由,search为查询字符串,hash就是锚点hash。实际渲染在页面上就是这样的:

<a href="/?name=geralt#the-hash">home</a>

这里的关键点在state上,这里设置state的loading为true,并不是匹配路由"/"根组件state,也不是Link所属组件state,而是匹配路由根组件的props.location.state的loading为true,要特别注意这一点。

replace:bool

一个布尔值,当为true(或只添加属性没有值),表示在历史栈中,用该新的地址覆盖上一个旧地址 。

<Router>
    <Link to="/a">a</Link>
    <Link to="/b">b</Link>
    <Link to="/c" replace={true}>c</Link>
    <Link to="/d">d</Link>
</Router>

依次点击a、b、c、d,然后点后退,你以为是b、a吗?错啦,实际上是c、a。

c覆盖上一个历史栈,因为是b到c的,所以b的历史栈被c覆盖了,所以后退就是c、a。


<NavLink>

这是<Link>的特殊版本,to、replace属性用法与前者一致。

试想这么一种情况,我想让匹配当前路由的<Link>渲染的a有个底色,怎么做?

import React from 'react';
import ReactDOM from 'react-dom';
import {
    BrowserRouter as Router,
    Link,
    Route
} from 'react-router-dom';

class MyComponent extends React.Component{
    render(){
        return(
            <Router>
                <div>
                    <Link to="/">Home</Link>
                    <Link to="/about">About</Link>
                    <Route path="/" component={()=>(<h1>Home</h1>)} />
                    <Route path="/about" component={()=>(<h1>About</h1>)} />
                </div>
            </Router>
        );
    }
}
ReactDOM.render(<MyComponent/>,document.querySelector("#root"));

如果这么写,MyComponent组件的render只有第一次渲染才会执行,切换路由的时候是不会触发该组件的任何生命周期函数,也就无法在该组件的生命周期函数内做操作。

有一种再次封装<Link>组件的方式可以实现,但等讲到Route组件的时候再说。现在<NavLink>就派上用场了。


activeClassName:string

当路由与该导航匹配,则添加该className,这个className可以是多个。

<Router>
    <div>
        <NavLink to="/" activeClassName="active">Home</NavLink>
        <NavLink to="/about" activeClassName="active">About</NavLink>
        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

activeStyle:obj

当路由与该导航匹配,则添加样式。

<Router>
    <div>
        <NavLink to="/" activeStyle={{color:"red"}}>Home</NavLink>
        <NavLink to="/about" activeStyle={{color:"red"}}>About</NavLink>
        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

如果你亲自写了,就会发现路由"/"总是有active的className、字体总是红色。这是因为对于"/about"这个路由,也是匹配"/"的。为了解决这个问题,可以设置exact属性和strict属性。

exact:bool

设置匹配模式是否为精确匹配。

<Router>
    <div>
        <NavLink exact to="/" activeClassName="active">Home</NavLink>
        <NavLink exact to="/about" activeClassName="active">About</NavLink>
        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

这样,在访问"/about"路由的时候,"/"就不会也添加active的className了。

strict:bool

设置匹配模式是否为严格匹配。

对于"/about"和"/about/",如果不设置strict,会认为是相同的路由(虽然实际应用中的确是相同的)

<Router>
    <div>
        <NavLink exact strict to="/" activeClassName="active">Home</NavLink>
        <NavLink exact strict to="/about" activeClassName="active">About</NavLink>
        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

一般这个属性相对用的较少,而exact用的很多。

isActive:func

当导航激活时触发该函数。

<Router>
    <div>
        <NavLink exact to="/" isActive={(match,location)=>{console.log(match,location)}}>Home</NavLink>
        <NavLink exact to="/about" isActive={(match,location)=>{console.log(match,location)}}>About</NavLink>
        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

当设置了该属性,activeClassName和activeStyle就不会生效了。

该函数有2个参数,match和location,上述2个函数无论匹配哪个路由,都会触发,只是只有匹配成功的路由,match才会正确返回,否则返回null。对于match和location后边会专门介绍,这里就不讲了。

location:obj

这个属性是配合isActive用的,相当于重写isActive的第二个参数location,注意配置的location会影响第一个参数match。

<Router>
    <div>
        <NavLink exact to="/" 
            location={{pathname:"/"}} 
            isActive={(match,location)=>{console.log(match,location)}}
        >Home</NavLink>

        <NavLink exact to="/about" 
            location={{pathname:"/about"}} 
            isActive={(match,location)=>{console.log(match,location)}}
        >About</NavLink>

        <Route exact path="/" component={()=>(<h1>Home</h1>)} />
        <Route exact path="/about" component={()=>(<h1>About</h1>)} />
    </div>
</Router>

当设置了该属性,activeClassName和activeStyle就不会生效了。

对于上例,不管匹配那个路由,match都不是null而是一个完整的对象。其中配置了location的pathname是关键点,如果location没有pathname,那么match就是null了。

results matching ""

    No results matching ""